package com.googlecode.weathergram;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Locale;

import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.location.Location;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import com.googlecode.weathergram.GeoLocationService.GeoLocationBinder;

public class WeatherService extends Service {

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		initService();
		return START_NOT_STICKY;
	}

	@Override
	public IBinder onBind(Intent intent) {
		initService();
		return binder;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		if (geoLocBinder != null)
			unbindService(geoLocConn);
	}

	public class WeatherBinder extends Binder {
		public Location getLocation() {
			return geoLocBinder.getCurrentLocation();
		}

		public WeatherData getData() {
			Location loc = getLocation();
			return getWeatherData(loc.getLatitude(), loc.getLongitude());
		}

		public boolean isFullyLoaded() {
			return geoLocBinder != null;
		}
	}

	private IBinder binder = new WeatherBinder();

	private GeoLocationBinder geoLocBinder;
	private ServiceConnection geoLocConn = new ServiceConnection() {
		@Override
		public void onServiceDisconnected(ComponentName name) {
			geoLocBinder = null;
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			geoLocBinder = (GeoLocationBinder) service;
		}
	};

	private void initService() {
		Intent geoLoc = new Intent(this, GeoLocationService.class);
		bindService(geoLoc, geoLocConn, BIND_AUTO_CREATE);

		initApi();

		Log.i(getClass().getSimpleName(), "Service initialized");
	}

	public class WeatherData {
		private String city;
		private double temp;

		public void setCity(String city) {
			this.city = city;
		}

		public void setTemp(double temp) {
			this.temp = temp;
		}

		public String getCity() {
			return city;
		}

		public String getTemp() {
			return temp + " °" + (apiUnit == "metric" ? "C" : "F");
		}
	}

	private WeatherData getWeatherData(double latitude, double longitude) {
		String request = "lat=" + latitude + "&lon=" + longitude;
		WeatherData data = new WeatherData();

		try {
			String response = readWeatherApi(request);
			JSONObject obj = new JSONObject(response);

			data.setCity(obj.get("name").toString());
			data.setTemp(Double.valueOf(((JSONObject) obj.get("main")).get("temp")
					.toString()));

		} catch (Exception e) {
			e.printStackTrace();
		}

		return data;
	}

	private static final String API_URL = "http://api.openweathermap.org/data/2.5/weather";
	private static final String API_APP_ID = "209aecf969627a6a7a00702050301021";

	private String apiUnit;
	private String apiConfig;

	@SuppressLint("DefaultLocale")
	private void initApi() {
		String locale = Locale.getDefault().getLanguage();
		String country = Locale.getDefault().getCountry().toLowerCase();

		String apiLang = "en";
		if (!"".equals(locale))
			apiLang = locale;

		if ("us".equals(country))
			apiUnit = "imperial";
		else
			apiUnit = "metric";

		apiConfig = //
		"appid=" + API_APP_ID //
				+ "&units=" + apiUnit //
				+ "&lang=" + apiLang;
	}

	private String readWeatherApi(String request) {
		StringBuilder responseString = new StringBuilder();

		HttpClient client = new org.apache.http.impl.client.DefaultHttpClient();
		HttpGet getRequest = new HttpGet(API_URL + "?" + apiConfig + "&" + request);

		HttpResponse response;
		try {
			response = client.execute(getRequest);

			StatusLine status = response.getStatusLine();
			int statusCode = status.getStatusCode();

			if (statusCode == 200) {
				InputStreamReader inputStreamReader = new InputStreamReader(response
						.getEntity().getContent());
				BufferedReader reader = new BufferedReader(inputStreamReader);

				String line;
				while ((line = reader.readLine()) != null)
					responseString.append(line);
			} else {
				Log.e(getClass().getSimpleName(), "Request of Weather-API failed");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return responseString.toString();
	}
}
